<?php
declare (strict_types = 1);
namespace app\admin\logic\user;

use app\admin\model\user\Account as AccountModel;
use app\admin\model\user\Token as UserTokenModel;
use think\helper\Str;

class Token extends UserTokenModel
{
    /**
     * 生成token
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-10
     * @param    AccountModel                      $user [description]
     * @return   [type]                               [description]
     */
    protected function createToken(AccountModel $user)
    {
        $ak = Str::random(16);
        $sk = Str::random(16);
		// ->whereAdminUserId($user->id)
        if ($this->whereAk($ak)->whereSk($sk)->find()) {
            return $this->createToken($user);
        }

        return $this->data(['ak' => $ak, 'sk' => $sk, 'admin_user_id' => $user->id])->save();
    }

    /**
     * 获取token
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-10
     * @param    AccountModel                      $user        [description]
     * @param    string                         $device_type 设备类型 app pc uniapp
     * @return
     */
    public function getToken(AccountModel $user)
    {
        $token = $this->where('admin_user_id', $user->id)->findOrEmpty();

        if ($token->isEmpty()) {
            // 创建token
            $this->createToken($user);
        }

        return $this->bindToken($user, $this->ak, $this->sk);

    }

    /**
     * 给用户模型绑定授权
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-11
     * @param    AccountModel                      $user [description]
     * @param    [type]                         $ak   [description]
     * @param    [type]                         $sk   [description]
     * @return   [type]                               [description]
     */
    public function bindToken(AccountModel $user, $ak, $sk)
    {
        $user->auth_scope = request()->device_type;
        $user->auth_token = [
            'ak' => $ak,
            'sk' => $sk,
        ];

        return $user;
    }

    /**
     * 根据token获取用户
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-10
     * @param    string                         $ak [description]
     * @param    string                         $sk [description]
     * @return   [type]                             [description]
     */
    public function getUserWithToken(string $ak, string $sk)
    {
        $token = $this->where('ak', $ak)->where('sk', $sk)->findOrEmpty();
        if ($token->isEmpty()) {
            return false;
        }

        return $token->user;
    }

    /**
     * 清空所有token
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-10
     * @param    AccountModel                      $user [description]
     * @return   [type]                               [description]
     */
    public function clearToken(AccountModel $user): void
    {
        $this->where('admin_user_id', $user->id)->delete();
    }

    /**
     * 刷新当前用户的token
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-10
     * @param    AccountModel                      $user [description]
     * @return   [type]                               [description]
     */
    public function refreshToken(AccountModel $user)
    {
        // 未查询到直接执行绑定
        $token = $this->whereAdminUserId($user->id)->find();
        if (!$token) {
            $this->createToken($user);
            return $this->bindToken($user, $this->ak, $this->sk);
        }
        $ak = Str::random(16);
        $sk = Str::random(16);

        $token->ak = $ak;
        $token->sk = $sk;

        $token->save();

        return $this->bindToken($user, $ak, $sk);
    }

}
